FindVO = BaseView:Extend()

local insert = table.insert

FindVO.POS_TO_TYPE = {
    DIRE = 1,
    SIDE = 2
}

local COST_DIRE = 1
local COST_SIDE = 1.4

FindVO.POS_COUNTER = {
    [1] = {x = 0 , y = 1},
    [2] = {x = 1 , y = 1},
    [3] = {x = 1 , y = 0},
    [4] = {x = 1 , y = -1},
    [5] = {x = 0 , y = -1},
    [6] = {x = -1 , y = -1},
    [7] = {x = -1 , y = 0},
    [8] = {x = -1 , y = 1},
}

function FindVO:New()
    local o = FindVO.super.New(self)
    self.open_list = {}
    self.close_list_dic = {}

    self.cache_in_close = {}        --已经在关闭列表中的开启列表的index
    return o
end

function FindVO:SetData(start_pos , target_pos , find_call_back)
    self.start_pos = start_pos
    self.find_call_back = find_call_back
    self.start_pos_str = self:ParsePosToStr(start_pos)
    self.target_pos = {x = math.ceil(target_pos.x),y = math.ceil(target_pos.y)}
    self.target_pos_str = self:ParsePosToStr(target_pos)
    self:GetPointMinCost(start_pos)
end

function FindVO:GetPointMinCost(pos)
    pos = {x = math.ceil(pos.x),y = math.ceil(pos.y)}
    local curr_main_pos_str = self:ParsePosToStr(pos)
    if curr_main_pos_str == self.target_pos_str then
        local result = self:HandlerFindSuccess()
        if self.find_call_back then
            self.find_call_back (result)
        end
        return result
    end
    --获得四周八个方向的点
    --从上开始 顺时针
    for i = 1, 8 do
        local calc_pos = FindVO.POS_COUNTER[i]
        local curr_pos = {x = calc_pos.x + pos.x , y = calc_pos.y + pos.y}
        if not self:CheckPointInOpen(curr_pos) then
            local cost = 0
            if i == 1 or i == 3 or i == 5 or i == 7 then
                cost = cost + COST_DIRE
            else
                cost = cost + COST_SIDE
            end

            --计算到达终点的距离
            local target_cost = math.abs(self.target_pos.x - curr_pos.x) + math.abs(self.target_pos.y - curr_pos.y)
            cost = cost + target_cost

            insert(self.open_list,{cost = cost , pos = self:ParsePosToStr(curr_pos) , parent = curr_main_pos_str , pos_tab = curr_pos})
        end
    end

    --排序 拿最小的
    table.sort(self.open_list,function(a, b)
        return a.cost < b.cost
    end)
    if self.open_list[1] then
        local node = self.open_list[1]
        self.close_list_dic[node.pos] = node
        self:GetPointMinCost(node.pos_tab)
    end
end

function FindVO:CheckPointInOpen(pos)
    local str = self:ParsePosToStr(pos)
    for i, v in ipairs(self.open_list) do
        if v.pos == str then
            return true
        end
    end
    return false
end

--寻路成功
function FindVO:HandlerFindSuccess()
    print("寻路成功~~~~~~")
    local str = ""
    local find_result = {}
    local node = self.close_list_dic[self.target_pos_str]
    if node then
        while node and node.parent ~= self.start_pos do
            str = str .. " -- " .. node.pos
            table.insert(find_result,node.pos_tab)
            node = self.close_list_dic[node.parent]
        end
        str = str .. " -- " .. self.start_pos_str
        table.insert(find_result,self.start_pos)
    end
    return find_result
end

function FindVO:ParsePosToStr (pos)
    return pos.x .. "@" .. pos.y
end